package com.missilike.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonArray;
import com.missilike.core.config.WxMappingJackson2HttpMessageConverter;
import com.missilike.core.constant.IMConstant;
import com.missilike.core.domain.im.IMAccount;
import com.missilike.core.domain.im.IMCallbackRequestBody;
import com.missilike.core.domain.im.IMProperties;
import com.missilike.core.domain.im.IMResponseBody;
import com.missilike.core.enums.IMAccountType;
import com.missilike.core.service.IIMService;
import com.tls.tls_sigature.tls_sigature;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class IMService implements IIMService {
    private final IMProperties imProperties;
    private final RestTemplate restTemplate;
    private final RedisTemplate redisTemplate;

    @Autowired
    public IMService(RedisTemplate redisTemplate, IMProperties imProperties, RestTemplate restTemplate) {
        restTemplate.getMessageConverters().add(new WxMappingJackson2HttpMessageConverter());
        this.redisTemplate = redisTemplate;
        this.imProperties = imProperties;
        this.restTemplate = restTemplate;
    }


    @Override
    public String getUserSign(String userAccount) {
        String userSign = (String) redisTemplate.opsForValue().get(IMConstant.IM_REDIS_PREFIX + userAccount);
        if (StringUtils.isBlank(userSign)) {
            long expire = 30 * 24 * 3600;//失效时间
            tls_sigature.GenTLSSignatureResult result = tls_sigature.GenTLSSignatureEx(imProperties.getSdkAppID(), userAccount, imProperties.getPrivateKey(), expire);
            if (StringUtils.isNotBlank(result.errMessage)) {
                log.error("获取签名错误:{}", result.errMessage);
                return null;
            }
            //预留2天的时间防止获取的签名过期
            redisTemplate.opsForValue().set(IMConstant.IM_REDIS_PREFIX + userAccount, result.urlSig, expire - 2 * 24 * 3600, TimeUnit.SECONDS);
            userSign = result.urlSig;
        }
        return userSign;
    }

    @Override
    public String getUserSign(Long userAccount) {
        if (userAccount != null) {
            return getUserSign(String.valueOf(userAccount));
        }
        return null;
    }

    @Override
    public IMResponseBody handleChatCallback(String sdkAppid, String clientIP, String optPlatform, IMCallbackRequestBody requestBody) {
        IMResponseBody responseBody = new IMResponseBody("OK", "", 0);
        return responseBody;
    }

    @Override
    public boolean exportAccountToIM(Long accountId, String nickName, String faceUrl, IMAccountType type) {
        String account = String.valueOf(accountId);
        String exportToIMUrl = IMConstant.IM_BASE_URL + "/" + IMConstant.IM_OPEN_LOGIN_SVC + "/" + IMConstant.IM_ACCOUNT_IMPORT;
        String finalUrl = getCommonParam(exportToIMUrl);
        if (StringUtils.isBlank(nickName)) {
            nickName = account;
        }
        IMAccount imAccount = new IMAccount(account, nickName, faceUrl, type.getValue());
        IMResponseBody responseBody = restTemplate.postForObject(finalUrl, JSON.toJSONString(imAccount), IMResponseBody.class);
        if (responseBody != null && StringUtils.isBlank(responseBody.getErrorInfo())) {
            return true;
        }
        log.info("account:{},导入IM失败:{},errorCode:{}", account, responseBody.getErrorInfo(), responseBody.getErrorCode());
        return false;
    }

    @Override
    public boolean exportNormalAccountToIM(Long account, String nickName, String faceUrl) {
        return exportAccountToIM(account, nickName, faceUrl, IMAccountType.NORMAL);
    }

    @Override
    public boolean addFriend(Long fromAccount, Long toAccount) {
        String addFriendUrl = IMConstant.IM_BASE_URL + "/" + IMConstant.IM_SNS + "/" + IMConstant.FRIEND_ADD;
        String finalUrl = getCommonParam(addFriendUrl);

        JSONObject request = new JSONObject();
        request.put(IMConstant.FROM_ACCOUNT, String.valueOf(fromAccount));
        request.put(IMConstant.ADD_TYPE, "Add_Type_Both");
        request.put(IMConstant.FORCE_ADDFLAGS, 1);
        JSONArray item = new JSONArray();
        JSONObject friend = new JSONObject();
        friend.put(IMConstant.TO_ACCOUNT, String.valueOf(toAccount));
        friend.put(IMConstant.ADD_SOURCE,"AddSource_Type_SERVER");
        item.add(friend);
        request.put(IMConstant.ADD_FRIEND_ITEM,item);
        IMResponseBody responseBody = restTemplate.postForObject(finalUrl, request.toJSONString(), IMResponseBody.class);
        if (responseBody != null && StringUtils.isBlank(responseBody.getErrorInfo())) {
            return true;
        }
        log.info("fromAccount:{},toAccount:{},添加好友失败:{},errorCode:{}", fromAccount,toAccount, responseBody.getErrorInfo(), responseBody.getErrorCode());
        return false;
    }


    private String getCommonParam(String url) {
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url).queryParam(IMConstant.USER_SIG, getUserSign(imProperties.getAdmin()))
                .queryParam(IMConstant.IDENTIFIER, imProperties.getAdmin())
                .queryParam(IMConstant.SDK_APP_ID, imProperties.getSdkAppID())
                .queryParam(IMConstant.RANDOM, String.valueOf(RandomUtils.nextInt(0, Integer.MAX_VALUE)))
                .queryParam(IMConstant.CONTENT_TYPE, "json");

        return builder.toUriString();
    }
}
